import type { ArtColumn } from 'ali-react-table';
import _ from 'lodash';

// 平铺后的tbaleColumn
export type tileColumnType = {
  name: ArtColumn['name'];
  code: ArtColumn['code'];
  precise?: number;
};

// 聚合维度数据处理成列表可用数据，和导出数据
export type buildDimensionTableDataType = {
  tableTreeData: any[];
  exportData: any[];
};

// 将列表数据处理成charts数据
export type buildDimensionChartDataType = {
  filterOption: { label: string; value: string | number }[][];
  chartsArr: any[];
  valIndex: number[];
};

//扩展列表配置数据
export interface extendColumnsType extends Omit<ArtColumn, 'children'> {
  precise?: number;
  transforFn?: (val: any) => any;
  children?: extendColumnsType[];
}

// 生成时点方法 24时点或96时点
const generateTimeArray = (count: number) => {
  const result = [];
  if (count === 24) {
    for (let i = 1; i <= 24; i++) {
      const hour = i < 10 ? `0${i}` : `${i}`;
      result.push(`${hour}00`);
    }
  } else if (count === 96) {
    for (let i = 0; i < 96; i++) {
      const totalMinutes = (i + 1) * 15;
      const hour = Math.floor(totalMinutes / 60);
      const minute = totalMinutes % 60;
      if (totalMinutes === 1440) {
        // 24:00 特殊处理
        result.push('2400');
      } else {
        const hourStr = hour < 10 ? `0${hour}` : `${hour}`;
        const minStr = minute === 0 ? '00' : minute < 10 ? `0${minute}` : `${minute}`;
        result.push(`${hourStr}${minStr}`);
      }
    }
  }
  return result;
};

const isIn24 = (val: number | string) => {
  const num = Number(val);
  return num >= 1 && num <= 24;
};

const isIn96 = (val: number | string) => {
  const num = Number(val);
  return num >= 1 && num <= 96;
};

// 主要作用用于平铺列表的Column，因为有些页面Column是树形结构需要拉平在处理列表数据
const tileTbaleColumn = (columns: extendColumnsType[]): tileColumnType[] => {
  const tileColumn: tileColumnType[] = [];
  const recursion = (arr: extendColumnsType[]) => {
    for (let i = 0; i < arr.length; i++) {
      const item = arr[i];
      if (item.children && item.children.length > 0) {
        recursion(item.children);
      } else {
        const col: any = {
          name: item.name,
          code: item.code,
        };
        if (item.precise) {
          col.precise = item.precise;
        }
        if (item.transforFn) {
          col.transforFn = item.transforFn;
        }
        tileColumn.push(col);
      }
    }
  };
  recursion(columns);
  return tileColumn;
};

// 聚合维度列表大多没有id字段，这里生成一个唯一的id
const generateId = () => {
  // 生成8位随机字母+数字的uuid
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let uuid = '';
  for (let i = 0; i < 8; i++) {
    uuid += chars[_.random(0, chars.length - 1)];
  }
  // 再拼接一个当前时间戳和一个4位随机数字，保证唯一性
  uuid += '-' + Date.now() + '-' + _.random(1000, 9999);
  return uuid;
};

// 根据列表项项配置把数据转换成列表支持的数据格式
const itemDataByColumnsAndArr = (
  columns: extendColumnsType[],
  arr: any[],
  point?: string,
  pointArr?: string[],
): { newArr: any[]; tableItemData: any } => {
  const item: any = { id: generateId() };
  const newArr: any[] = [];
  columns.forEach((c: extendColumnsType, i: number) => {
    if (c.code) {
      let val = arr[i];
      if (c.precise) {
        val = Number(val).toFixed(c.precise);
      }
      if (c.transforFn && _.isFunction(c.transforFn)) {
        val = c.transforFn(val);
      }
      // 此处判断或许不太严谨
      // 此处判断处理时点后端可能会返回1，2，3，这种形式的试点，需要转换成0100，c.code此处可扩展动态key，目前写死‘dimension’
      if (point && pointArr && pointArr.length > 0 && c.code === 'dimension') {
        if (point === '24' && isIn24(val)) {
          val = pointArr[Number(val) - 1];
        }
        if (point === '96' && isIn96(val)) {
          val = pointArr[Number(val) - 1];
        }
      }
      newArr.push(val);
      item[c.code] = val;
    }
  });
  return {
    tableItemData: item,
    newArr,
  };
};

// 处理聚合维度数据
const buildDimensionTableData = (
  columns: ArtColumn[],
  tableData: any[],
  point?: string,
): buildDimensionTableDataType => {
  let tableTreeData: buildDimensionTableDataType['tableTreeData'] = [];
  const exportData: any[] = [];
  let pointArr: string[] = [];

  if (point) {
    pointArr = generateTimeArray(Number(point));
  }

  const recursion = (obj: any, parentKey?: string) => {
    const dataSource: any[] = [];
    const keyArr = sortObj(obj);
    keyArr.forEach((key) => {
      if (_.isArray(obj[key])) {
        const arr: any[] = obj[key];
        arr.unshift(key === 'total' ? '合计' : key);
        const { tableItemData, newArr } = itemDataByColumnsAndArr(columns, arr, point, pointArr);
        exportData.push(newArr);
        dataSource.push(tableItemData);
      }
      if (!_.isArray(obj[key]) && _.isObject(obj[key])) {
        const cData = { ...obj[key] };
        let item: any = {};
        if (cData.total) {
          const arr: any[] = cData.total;
          arr.unshift(key);
          const { tableItemData, newArr } = itemDataByColumnsAndArr(columns, arr, point, pointArr);
          exportData.push(newArr);
          item = {
            ...tableItemData,
          };
          delete cData.total;
        }
        item.children = recursion(cData, key);
        dataSource.push(item);
      }
    });
    return dataSource;
  };

  if (tableData && columns) {
    tableTreeData = recursion(tableData);
  }

  return {
    tableTreeData,
    exportData,
  };
};

// 通过buildDimensionTableData处理后的列表数据生成charts数据，和筛选项
const buildDimensionChartData = (
  tableTreeData: any[],
  order: string[],
  dimensionKey?: string,
): buildDimensionChartDataType => {
  dimensionKey = dimensionKey ? dimensionKey : 'dimension';
  const filterOption: any[] = [];
  const valIndex: number[] = [];
  const newOrder = order.slice(0, -1);
  const newTableTreeData = tableTreeData.slice(1);
  let node: any = undefined;
  let chartsArr = [];

  if (order.length > 1) {
    newOrder.forEach((v, i) => {
      valIndex.push(0);
      node = newTableTreeData[valIndex[i]];
      const options = getSelectOptions(i === 0 ? newTableTreeData : node.children, dimensionKey);
      filterOption.push(options);
    });

    const lastNode = findNodeByIndexPath(tableTreeData, valIndex);
    if (lastNode && lastNode.children) {
      chartsArr = lastNode.children;
    }
  } else {
    chartsArr = newTableTreeData;
  }

  return {
    filterOption,
    chartsArr,
    valIndex,
  };
};

const getSelectOptions = (arr: any, dimensionKey: string) => {
  const options = [];
  for (let n = 0; n < arr.length; n++) {
    if (arr[n][dimensionKey] !== '合计') {
      options.push({
        label: arr[n][dimensionKey],
        value: arr[n][dimensionKey],
      });
    }
  }
  return options;
};

const findNodeByIndexPath = (tree: any[], indexArr: number[]): any | undefined => {
  let node: any = undefined;
  let currentArr = tree.slice(1);
  for (let i = 0; i < indexArr.length; i++) {
    const idx = indexArr[i];
    if (!currentArr || !Array.isArray(currentArr) || idx >= currentArr.length) {
      return undefined;
    }
    node = currentArr[idx];
    // 如果不是最后一个索引，进入 children
    if (i < indexArr.length - 1) {
      currentArr = node.children;
    }
  }
  return node;
};

// 是否是时间 格式是 YYYY-MM-DD
const isDateString = (str: string) => /^\d{4}-\d{2}-\d{2}$/.test(str);
// 是否是数字
const isNumberString = (str: string) => /^\d+$/.test(str);
// 是否是字母
const isAlphaString = (str: string) => /^[A-Za-z]+$/.test(str);
// 是否是中文
const isChineseString = (str: string) => /^[\u4e00-\u9fa5]+$/.test(str);

const sortObj = (obj: any) => {
  return Object.keys(obj).sort((a, b) => {
    // total 永远在第一个
    if (a === 'total') return -1;
    if (b === 'total') return 1;
    // 类型优先级：日期 > 数字 > 字母 > 中文
    const getTypeOrder = (str: string) => {
      if (isDateString(str)) return 4;
      if (isNumberString(str)) return 3;
      if (isAlphaString(str)) return 2;
      if (isChineseString(str)) return 1;
      return 0;
    };
    const aType = getTypeOrder(a);
    const bType = getTypeOrder(b);
    if (aType !== bType) {
      return aType - bType; // 升序：类型优先级小的排前面
    }
    if (aType === 4) {
      return new Date(a).getTime() - new Date(b).getTime(); // 日期升序
    }
    if (aType === 3) {
      return Number(a) - Number(b); // 数字升序
    }
    if (aType === 2) {
      return a.localeCompare(b, 'en'); // 字母升序
    }
    if (aType === 1) {
      return a.localeCompare(b, 'zh'); // 中文升序
    }
    return a.localeCompare(b, 'zh'); // 其他按中文升序
  });
};

const findOptionsByKey = (key: string, filterOption: any) => {
  const afterKeys: string[] = [];
  const recursion = (parentKey: string) => {
    if (filterOption[parentKey]) {
      const first = filterOption[parentKey][0];
      afterKeys.push(first.value);
      recursion(first.value);
    }
  };

  recursion(key);
  return afterKeys;
};

const buildDimensionOptions = (filterOption: any) => {
  let listVal: string[] = [];
  const first = filterOption.first;
  if (first && first.length > 0) {
    const firstVal = first[0].value;
    listVal = [firstVal, ...findOptionsByKey(firstVal, filterOption)];
  }
  return listVal;
};

// 将树性结构列表数据专程前端导出数据 // 目前只针对个别页面，比如省间现货复盘
const buildExportDataByTableData = (
  tableTreeData: any[],
  tileTbaleColumn: extendColumnsType[],
): any[][] => {
  const exportData: any[] = [];

  if (tableTreeData && tableTreeData.length > 0) {
    const recursion = (arr: any[]) => {
      for (let i = 0; i < arr.length; i++) {
        const dataItem = arr[i];
        const row: any[] = [];
        tileTbaleColumn.forEach((v: extendColumnsType) => {
          if (v.code) {
            row.push(dataItem[v.code]);
          }
        });
        exportData.push(row);
        if (dataItem.children && dataItem.children.length > 0) {
          recursion(dataItem.children);
        }
      }
    };
    recursion(tableTreeData);
  }

  return exportData;
};

export {
  tileTbaleColumn,
  buildDimensionTableData,
  buildDimensionChartData,
  buildDimensionOptions,
  findNodeByIndexPath,
  buildExportDataByTableData,
};
